bitkeeper revision 1.44 (3e4e65159dO6gZq2mxyfYFsgJFKbtw)
authorkaf24@labyrinth.cl.cam.ac.uk <kaf24@labyrinth.cl.cam.ac.uk>
Sat, 15 Feb 2003 16:04:37 +0000 (16:04 +0000)
committerkaf24@labyrinth.cl.cam.ac.uk <kaf24@labyrinth.cl.cam.ac.uk>
Sat, 15 Feb 2003 16:04:37 +0000 (16:04 +0000)
dev.c, vif.h, network.c:
  Fixed network transmit. Update consumer index *after* packet is transmitted :-)

xen-2.4.16/common/network.c
xen-2.4.16/include/xeno/vif.h
xen-2.4.16/net/dev.c

index 80fad27cc7e9d31775ec0bab86049bda47b65e44..687d3e2403a5a86304a83391341f104446ad34d9 100644 (file)
@@ -65,22 +65,18 @@ net_vif_t *create_net_vif(int domain)
     new_ring = dom_task->net_ring_base + dom_task->num_net_vifs;
     memset(new_ring, 0, sizeof(net_ring_t));
 
-    // allocate the shadow ring.  
-    // maybe these should be kmem_cache instead of kmalloc?
-    
     shadow_ring = kmalloc(sizeof(net_shadow_ring_t), GFP_KERNEL);
     if (shadow_ring == NULL) goto fail;
     
-    shadow_ring->tx_ring = kmalloc(TX_RING_SIZE 
-                    * sizeof(tx_shadow_entry_t), GFP_KERNEL);
     shadow_ring->rx_ring = kmalloc(RX_RING_SIZE
                     * sizeof(rx_shadow_entry_t), GFP_KERNEL);
-    if ((shadow_ring->tx_ring == NULL) || (shadow_ring->rx_ring == NULL))
+    if ( shadow_ring->rx_ring == NULL )
             goto fail;
 
     shadow_ring->rx_prod = shadow_ring->rx_cons = shadow_ring->rx_idx = 0;
+    shadow_ring->tx_cons = 0;
     
-    // fill in the new vif struct.
+    /* Fill in the new vif struct. */
     
     new_vif->net_ring = new_ring;
     new_vif->shadow_ring = shadow_ring;
@@ -127,7 +123,6 @@ void destroy_net_vif(struct task_struct *p)
     sys_vif_list[p->net_vif_list[i]->id] = NULL; // system vif list not gc'ed
     write_unlock(&sys_vif_lock);        
    
-    kfree(p->net_vif_list[i]->shadow_ring->tx_ring);
     kfree(p->net_vif_list[i]->shadow_ring->rx_ring);
     kfree(p->net_vif_list[i]->shadow_ring);
     kmem_cache_free(net_vif_cache, p->net_vif_list[i]);
@@ -297,21 +292,23 @@ int net_find_rule(u8 nproto, u8 tproto, u32 src_addr, u32 dst_addr, u16 src_port
     
     while (ent)
     {
-        if (    (    (ent->r.src_interface == src_vif) 
-                  || (ent->r.src_interface == VIF_ANY_INTERFACE) )
-
-             && (!((ent->r.src_addr ^ src_addr) & ent->r.src_addr_mask ))
-             && (!((ent->r.dst_addr ^ dst_addr) & ent->r.dst_addr_mask ))
-             && (!((ent->r.src_port ^ src_port) & ent->r.src_port_mask ))
-             && (!((ent->r.dst_port ^ dst_port) & ent->r.dst_port_mask ))
-
-             && (
-                     (ent->r.proto == NETWORK_PROTO_ANY)
-                  || ((ent->r.proto == NETWORK_PROTO_IP)  && (nproto == (u8)ETH_P_IP))
-                  || ((ent->r.proto == NETWORK_PROTO_ARP) && (nproto == (u8)ETH_P_ARP))
-                  || ((ent->r.proto == NETWORK_PROTO_TCP) && (tproto == IPPROTO_TCP))
-                  || ((ent->r.proto == NETWORK_PROTO_UDP) && (tproto == IPPROTO_UDP))
-                )
+        if ( ((ent->r.src_interface == src_vif)
+              || (ent->r.src_interface == VIF_ANY_INTERFACE)) &&
+
+             (!((ent->r.src_addr ^ src_addr) & ent->r.src_addr_mask )) &&
+             (!((ent->r.dst_addr ^ dst_addr) & ent->r.dst_addr_mask )) &&
+             (!((ent->r.src_port ^ src_port) & ent->r.src_port_mask )) &&
+             (!((ent->r.dst_port ^ dst_port) & ent->r.dst_port_mask )) &&
+             
+             ((ent->r.proto == NETWORK_PROTO_ANY) ||
+              ((ent->r.proto == NETWORK_PROTO_IP)  &&
+               (nproto == (u8)ETH_P_IP)) ||
+              ((ent->r.proto == NETWORK_PROTO_ARP) &&
+               (nproto == (u8)ETH_P_ARP)) ||
+              ((ent->r.proto == NETWORK_PROTO_TCP) &&
+               (tproto == IPPROTO_TCP)) ||
+              ((ent->r.proto == NETWORK_PROTO_UDP) &&
+               (tproto == IPPROTO_UDP)))
            )
         {
             break;
@@ -358,40 +355,34 @@ int __net_get_target_vif(u8 *data, unsigned int len, int src_vif)
     case ETH_P_ARP:
         if ( len < 28 ) goto drop;
         target = net_find_rule((u8)ETH_P_ARP, 0, ntohl(*(u32 *)(nh_raw + 14)),
-                        ntohl(*(u32 *)(nh_raw + 24)), 0, 0, 
-                        src_vif);
+                               ntohl(*(u32 *)(nh_raw + 24)), 0, 0, 
+                               src_vif);
         break;
 
     case ETH_P_IP:
         if ( len < 20 ) goto drop;
         h_raw =  data + ((*(unsigned char *)(nh_raw)) & 0x0f) * 4;
-        switch ( *(unsigned char *)(nh_raw + 9) )
-        {
-        case IPPROTO_UDP:
-        case IPPROTO_TCP:
-            target = net_find_rule((u8)ETH_P_IP,  *(u8 *)(nh_raw + 9),
-                    ntohl(*(u32 *)(nh_raw + 12)),
-                    ntohl(*(u32 *)(nh_raw + 16)),
-                    ntohs(*(u16 *)(h_raw)),
-                    ntohs(*(u16 *)(h_raw + 2)), 
-                    src_vif);
-            break;
-
-        default: // ip-based protocol where we don't have ports.
-            target = net_find_rule((u8)ETH_P_IP,  *(u8 *)(data + 9),
-                    ntohl(*(u32 *)(nh_raw + 12)),
-                    ntohl(*(u32 *)(nh_raw + 16)),
-                    0,
-                    0, 
-                    src_vif);
-        }
-        break;
-
+        
+        /* XXX For now, we ignore ports. */
+#if 0
+        target = net_find_rule((u8)ETH_P_IP,  *(u8 *)(nh_raw + 9),
+                               ntohl(*(u32 *)(nh_raw + 12)),
+                               ntohl(*(u32 *)(nh_raw + 16)),
+                               ntohs(*(u16 *)(h_raw)),
+                               ntohs(*(u16 *)(h_raw + 2)), 
+                               src_vif);
+#else
+        target = net_find_rule((u8)ETH_P_IP,  *(u8 *)(data + 9),
+                               ntohl(*(u32 *)(nh_raw + 12)),
+                               ntohl(*(u32 *)(nh_raw + 16)),
+                               0,
+                               0, 
+                               src_vif);
+#endif
     }
     return target;
     
-    drop:
-//printk("Drop case!\n");
+ drop:
     return VIF_DROP;
 }
 
index 7d2878dabfd5995f0e79396f59b69d1b936b40a8..4af4f244352ec1a661579f84a17036dae0dcc8b6 100644 (file)
  * TX_RING_SIZE and RX_RING_SIZE are defined in the shared network.h.
  */
 
-typedef struct tx_shadow_entry_st {
-    unsigned long addr;
-    unsigned long size;
-    int           status;
-    unsigned long flush_count;
-} tx_shadow_entry_t;
-
 typedef struct rx_shadow_entry_st {
     unsigned long addr;
     unsigned long size;
@@ -40,9 +33,9 @@ typedef struct rx_shadow_entry_st {
 } rx_shadow_entry_t;
 
 typedef struct net_shadow_ring_st {
-    tx_shadow_entry_t *tx_ring;
     rx_shadow_entry_t *rx_ring;
     unsigned int rx_prod, rx_cons, rx_idx;
+    unsigned int tx_cons; /* ahead of shared tx_cons */
 } net_shadow_ring_t;
 
 typedef struct net_vif_st {
index 4e36aa0d608d8ca28d97bd84fa5522094a620805..1ce6e9649eae68169006cccb18e8e67900501f51 100644 (file)
@@ -2003,6 +2003,7 @@ inline int init_tx_header(u8 *data, unsigned int len, struct net_device *dev)
         return 0;
 }
 
+
 /* 
  * tx_skb_release
  *
@@ -2017,11 +2018,21 @@ void tx_skb_release(struct sk_buff *skb)
 {
     int i;
     
-    for (i= 0; i < skb_shinfo(skb)->nr_frags; i++)
+    for ( i = 0; i < skb_shinfo(skb)->nr_frags; i++ )
         skb_shinfo(skb)->frags[i].page->tot_count--;
     
     skb_shinfo(skb)->nr_frags = 0; 
+
+    /*
+     * XXX This assumes that, per vif, SKBs are processed in-order!
+     * Also, like lots of code in here -- we assume direct access to the
+     * consumer and producer indexes. This is likely safe for the
+     * forseeable future.
+     */
+    sys_vif_list[skb->src_vif]->net_ring->tx_cons = 
+        TX_RING_INC(sys_vif_list[skb->src_vif]->net_ring->tx_cons);
 }
+
     
 /*
  * do_net_update:
@@ -2045,8 +2056,7 @@ long do_net_update(void)
     rx_shadow_entry_t *rx;
     unsigned long pfn;
     struct pfn_info *page;
-    unsigned long *g_pte;
-    
+    unsigned long *g_pte;    
     
     for ( j = 0; j < current->num_net_vifs; j++)
     {
@@ -2056,12 +2066,13 @@ long do_net_update(void)
 
         current_vif = current->net_vif_list[j];
         net_ring = current_vif->net_ring;
+        shadow_ring = current_vif->shadow_ring;
         
         /*
          * PHASE 1 -- TRANSMIT RING
          */
 
-        for ( i = net_ring->tx_cons; 
+        for ( i = shadow_ring->tx_cons; 
               i != net_ring->tx_prod; 
               i = TX_RING_INC(i) )
         {
@@ -2176,14 +2187,12 @@ long do_net_update(void)
                 unmap_domain_mem(g_data);
             }
         }
-        net_ring->tx_cons = i;
+        shadow_ring->tx_cons = i;
 
         /*
          * PHASE 2 -- RECEIVE RING
          */
 
-        shadow_ring = current_vif->shadow_ring;
-
         for ( i = shadow_ring->rx_prod; 
               i != net_ring->rx_prod; 
               i = RX_RING_INC(i) )